#include "..//include//VirtualPetHead"
#define BUF_SIZE 1024
#define FD_SIZE 1000
#define EPOLLEVENTS 1000
#define LISTENQ 10
#include<thread>
#include<pthread.h>


using namespace std;

thread t_Save;
void SaveThread(int fd);

int epoll_main()
{
    /* code */
    int servfd = sock_init(9877);
    do_epoll(servfd);
    close(servfd);
    return 0;
}

int sock_init(int port){
    int listenfd = -1;
    sockaddr_in servaddr;
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1)
    {
        cout << "Listen error!" << endl
             << "Errno: " << errno << " , "
             << strerror(errno);
        exit(0);
    }
    else
    {
        cout << "Listen success!\n";
    }
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    if (bind(listenfd, (sockaddr *)&servaddr, sizeof(servaddr)) == -1)
    {
        cout << "Bind error!" << endl
             << "Errno: " << errno << ", "
             << strerror(errno) << endl;
        exit(0);
    }
    else
    {
        cout << "Bind success!\n";
    }
    if (listen(listenfd, LISTENQ) == -1)
    {
        cout << "Listen error!" << endl
             << "Errno: " << errno << ", "
             << strerror(errno) << endl;
        return -1;
    }
    else
    {
        cout << "Listening......\n";
    }
    return listenfd;
}

void handle_event(int epollfd,epoll_event* events,int num,int listenfd,char* buf)
{
    int fd;
    for (int i = 0; i < num; i++)
    {
        /* code */
        fd = events[i].data.fd;
        if ((fd == listenfd) && (events[i].events & EPOLLIN))
        {
            cout<<"Accepting client ..."<<endl;
            handle_accept(epollfd, listenfd);
        }
        else if (events[i].events & EPOLLIN)
        {
            cout<<"Reading from client ..."<<endl;
            do_read(epollfd, fd, buf);
        }
        else if (events[i].events & EPOLLOUT)
        {
            cout<<"Writing to client ..."<<endl;
            //发送缓冲区
            char send[128];
            if(strcmp(buf,"bitHeart")==0){
                continue;
            }
            //合法检查
            if (CheckRecv(buf))
            {
                sprintf(send,DealMessage(fd,buf).c_str());
            }
            else
            {
                sprintf(send,"99;Message illegal!");
            }           
            //Socket写
            do_write(epollfd, fd, send);
        }
    }
    
}

void handle_accept(int epollfd,int listenfd)
{
    int clntfd;
    sockaddr_in clntaddr;
    socklen_t clntSZ = sizeof(clntaddr);
    clntfd = accept(listenfd, (sockaddr *)&clntaddr, &clntSZ);
    if (clntfd == -1)
    {
        cout << "Accept error!" << endl
             << "Errno: " << errno << " , "
             << strerror(errno);
        return;
    }
    else
    {
        cout << "Accept success!\n";
        cout << "Client IP: " << inet_ntoa(clntaddr.sin_addr) << ":" << clntaddr.sin_port << endl;
        add_event(epollfd, clntfd, EPOLLIN);
    }
}

void do_read(int epollfd,int fd,char*buf)
{
    int readNum = 0;
    readNum = read(fd, buf, BUF_SIZE);
    if (readNum <= 0)
    {
        close(fd);
        del_event(epollfd, fd, EPOLLIN);
    }
    else
    {
        buf[readNum] = 0;
        cout << "ClientSay: " << buf<<endl;
        fflush(stdout);
        modi_event(epollfd, fd, EPOLLOUT);
    }
    
}

void do_write(int epollfd,int fd,char*buf)
{
    int writeNum = 0;
    writeNum = write(fd, buf, strlen(buf));
    if (writeNum == -1)
    {
        close(fd);
        del_event(epollfd, fd, EPOLLOUT);
    }
    else
    {
        modi_event(epollfd, fd, EPOLLIN);
    }
    memset(buf, 0, BUF_SIZE);
    
}

void add_event(int epollfd,int fd,int state)
{
    epoll_event ev;
    ev.data.fd = fd;
    ev.events = state;
    AddPlayer(fd);
    epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev);
}

void modi_event(int epollfd,int fd,int state)
{
    epoll_event ev;
    ev.data.fd = fd;
    ev.events = state;
    epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &ev);

}

void del_event(int epollfd,int fd,int state)
{
    epoll_event ev;
    ev.data.fd = fd;
    ev.events = state;
    epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, &ev);
    DeletePlayer(fd);
}

void do_epoll(int listenfd)
{
    int epollfd;
    epoll_event events[EPOLLEVENTS];
    epollfd = epoll_create(FD_SIZE);
    char buf[BUF_SIZE];
    memset(buf, 0, BUF_SIZE);
    int sigNum;
    add_event(epollfd, listenfd, EPOLLIN);
    cout << "Server is running ......" << endl;
    while (1)
    {
        sigNum = epoll_wait(epollfd, events, EPOLLEVENTS, -1);
        handle_event(epollfd, events, sigNum, listenfd, buf);
    }
    close(epollfd);
}

bool CheckRecv(const char* recvStr){
    //最小长度：指令值;内容1;内容2   ---> len: 5
    if (strlen(recvStr)<5)
    {
        return false;
    }
    //分号开头或指令值不为数字：指令值;内容1;内容2 
    if (!isdigit(recvStr[0]))
    {
        return false;
    }
    //出现连续分号
    int count;//总分号数量（合法为2）
    for (int i=0;i<strlen(recvStr)-1;i++)
    {
        if (recvStr[i]==';')
        {
            count++;
            if (recvStr[i+1]==';')
            {
                return false;
            }            
        }        
    }
    if (count!=2)
    {
        return false;
    }       
    return true;    
}


void SaveThread(int fd){
    
}
